package TestPaperSystem.service.impl;

import TestPaperSystem.Dto.SimilarityDTO;
import TestPaperSystem.enmus.QuType;
import TestPaperSystem.entity.ExamPaperQu;
import TestPaperSystem.entity.Paper;
import TestPaperSystem.entity.Similarity;
import TestPaperSystem.mapper.SimilarityMapper;
import TestPaperSystem.service.ExamPaperQuService;
import TestPaperSystem.service.PaperService;
import TestPaperSystem.service.SimilarityService;
import TestPaperSystem.utils.codeClone.CodeVerify;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Nullable;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author xwj
 * @since 2023-05-03
 */
@Service
public class SimilarityServiceImpl extends ServiceImpl<SimilarityMapper, Similarity> implements SimilarityService {

    @Autowired
    ExamPaperQuService examPaperQuService;

    @Autowired
    PaperService paperService;

    @Resource
    SimilarityMapper similarityMapper;

    @Override
    public void getSimilarity(Paper paper) throws Exception{
        //找出需对比人的作答信息, 题目为编程题，是本人试卷，答案不为空
        List<ExamPaperQu> examPaperQuList = examPaperQuService.getBaseMapper()
                .selectList(new QueryWrapper<ExamPaperQu>().lambda()
                        .eq(ExamPaperQu::getPaperId , paper.getId())
                        .eq(ExamPaperQu::getQuType,QuType.PROGRAM))
                .stream()
                .filter(examPaperQu -> (!examPaperQu.getAnswer().equals("")
                        && examPaperQu.getActualScore() > 0))
                .collect(Collectors.toList());

        //除去本人外的相同考试答题人
        List<String> paperIds = paperService.getBaseMapper()
                .selectList(new QueryWrapper<Paper>().lambda().eq(Paper::getExamId , paper.getExamId())
                .ne(Paper::getId,paper.getId()))
                .stream()
                .map(Paper::getId)
                .collect(Collectors.toList());

        System.out.println(paperIds.size() + " " + examPaperQuList.size());
        if(paperIds.isEmpty() || examPaperQuList.isEmpty()){
            return;
        }
        List<Similarity> similarities = new ArrayList<>();
        for(ExamPaperQu item : examPaperQuList){
            int[] token_arr = CodeVerify.getInstance().getTokenArr(item.getAnswer());
            List<ExamPaperQu> examPaperQus  = examPaperQuService.getBaseMapper()
                    .selectList(new QueryWrapper<ExamPaperQu>().lambda()
                            .in(ExamPaperQu::getPaperId , paperIds)
                            .eq(ExamPaperQu::getQuId , item.getQuId()))
                    .stream()
                    .filter(examPaperQu -> examPaperQu.getActualScore() > 0)
                    .collect(Collectors.toList());

            for(ExamPaperQu var : examPaperQus){
                int[] compare_token_arr = CodeVerify.getInstance().getTokenArr(var.getAnswer());
                if(CodeVerify.getInstance().getSimilarity(token_arr , compare_token_arr)){

                    Similarity similarity = new Similarity();
                    similarity.setExamId(paper.getExamId());
                    similarity.setQuId(var.getQuId());
                    similarity.setUserIdA(paper.getUserId());
                    similarity.setUserIdB(paperService.getById(var.getPaperId()).getUserId());

                    similarities.add(similarity);
                }
            }

        }

        if(!similarities.isEmpty())
            this.saveBatch(similarities);
    }

    @Override
    public List<SimilarityDTO> getByExamId(String examId) {
        return similarityMapper.getByExamId(examId);
    }
}
